import * as React from 'react';
import Icon from './Icon';
import Input from './Input';
import Tree from './Tree';

const TreeNode = Tree.TreeNode;

export interface ITreeData {
  key: string;
  title: string;
  label?: string;
  children?: ITreeData[];
}

export interface ICheckedData {
  checkedKeys: string[];
  checkedValues: ITreeData[];
}

export interface ITransferState {
  checkedKeys?: string[];
  checkedValues?: ITreeData[];
  expandedKeys?: string[];
}

export interface ITransferProps {
  showSearch?: boolean;
  searchPlaceholder?: string;
  showInnerSelectedTitle?: boolean;
  showOuterSelectedTitle?: boolean;
  descriptionTitle?: string;
  showEmptySelect?: boolean;

  defaultExpandedKeys?: string[];
  defaultCheckedKeys?: string[];
  treeData?: ITreeData[];
  onCancel?: () => void;
  onRef?: (ref: React.Component) => void;
  onSave?: (data: ITreeData[]) => void;
  onSearchInputChange?: (value: string) => Promise<ITreeData[]>;
  onCheck: (keys: string[]) => void;

}

export default class Transfer extends React.Component<ITransferProps, any> {
  public static defaultProps = {
    showSearch: false, // 是否显示搜索框
    searchPlaceholder: '', // 搜索框提示文字
    showInnerSelectedTitle: false, // 是否显示内部已选择的标题
    showOuterSelectedTitle: false, // 是否显示外部已选择的标题
    descriptionTitle: '', // 选择的描述文字
    showEmptySelect: false, // 是否显示清空选择
    treeData: [],
  };

  public leftContentHead: HTMLDivElement | null = null;
  public rightContentHead: HTMLDivElement | null = null;

  constructor(props: ITransferProps) {
    super(props);
    this.state = {
      autoExpandParent: true,
      selectedKeys: [],
      searchValue: '',
      leftContentHeadHeight: 0,
      rightContentHeadHeight: 0,

      expandedKeys: props.defaultExpandedKeys || [],
      checkedKeys: [],
      checkedValues: [],
      treeData: props.treeData,
    };
    this.onExpand = this.onExpand.bind(this);
    this.onSelect = this.onSelect.bind(this);
    this.onCheck = this.onCheck.bind(this);
    this.renderTreeNodes = this.renderTreeNodes.bind(this);
    this.emptySelect = this.emptySelect.bind(this);
    this.onSave = this.onSave.bind(this);
    this.inputTextChange = this.inputTextChange.bind(this);
    this.renderEmptySelect = this.renderEmptySelect.bind(this);
    this.deleteSelect = this.deleteSelect.bind(this);
    this.getLeftContentHeadRef = this.getLeftContentHeadRef.bind(this);
    this.getRightContentHeadRef = this.getRightContentHeadRef.bind(this);
    this.getPreviousCheckedKeys = this.getPreviousCheckedKeys.bind(this);
    this.getPreviousExpandedKeys = this.getPreviousExpandedKeys.bind(this);
  }

  public componentDidMount() {
    if (this.props.onRef) {
      this.props.onRef(this);
    }
    if (this.props.defaultCheckedKeys && this.props.defaultCheckedKeys.length) {
      this.onCheck(this.props.defaultCheckedKeys);
    }
  }

  public onExpand(expandedKeys: string[]) {
    // console.log('onExpand', expandedKeys);
    // if not set autoExpandParent to false, if children expanded, parent can not collapse.
    // or, you can remove all expanded children keys.
    this.setState({
      autoExpandParent: false,
      expandedKeys,
    });
  }

  public uniqValues(values: ITreeData[]) {
    if (!values || !Array.isArray(values)) {
      return [];
    }
    const recordObject: { [key: string]: any } = {};
    const filterValues: ITreeData[] = [];
    values.forEach((value) => {
      if (!recordObject[value.key]) {
        recordObject[value.key] = value;
        filterValues.push(value);
      }
    });
    return filterValues;
  }

  // 树结构数据最多三层
  public getSearchDataAndExpandedKeys(treeData: ITreeData[], value: string) {
    let values: ITreeData[] = [];
    let expandedKeys: string[] = this.state.expandedKeys;
    if (!value) {
      return { values, expandedKeys };
    }

    // 第一层循环
    treeData.forEach((item: ITreeData) => {
      if (item.title.indexOf(value) > -1) {
        values.push(item);
      } else if (item.children && item.children.length) {
        // 第二层循环
        item.children.forEach((childItem) => {
          if (childItem.title.indexOf(value) > -1) {
            values.push(item);
            if (!expandedKeys.includes(item.key)) {
              expandedKeys.push(item.key);
            }
          } else if (childItem.children && childItem.children.length) {
            // 第三层循环
            childItem.children.forEach((childestItem) => {
              if (childestItem.title.indexOf(value) > -1) {
                values.push(item);
                if (!expandedKeys.includes(childItem.key)) {
                  expandedKeys.push(childItem.key);
                }
              }
            });
          }
        });
      }
    });
    values = this.uniqValues(values);
    return { values, expandedKeys };
  }

  public getDeepestData(treeData: ITreeData[], depth = 2) {
    const newDepth = depth--;
    let values: ITreeData[] = [];
    treeData.forEach((item: ITreeData) => {
      if (item.children && item.children.length && newDepth > 0) {
        const nextValues = this.getDeepestData(item.children, newDepth);
        values = values.concat(nextValues);
      } else {
        values.push(item);
      }
    });
    return values;
  }

  public getPreviousCheckedKeys() {
    return this.state.checkedKeys;
  }

  public getPreviousExpandedKeys() {
    return this.state.expandedKeys;
  }

  public onCheck(checkedKeys: string[]) {
    // checkedValues的key 可能不在树结构数据内
    const treeData = this.state.treeData || [];
    let checkedValues: ITreeData[] = this.state.checkedValues;

    // 获取最下层的数据和keys
    const deepestData = this.getDeepestData(treeData);
    const deepestDataKeys = deepestData.map((item) => item.key);
    // 提取选中keys中属于最下层的keys
    const filterCheckedKeys = checkedKeys.filter((key) => deepestDataKeys.includes(key));
    // 获取上一次选中的数据和keys
    const hasCheckedValues = deepestData.filter((item) => this.state.checkedKeys.includes(item.key));
    const hasCheckedkeys = hasCheckedValues.map((item: ITreeData) => item.key);

    // 取消的keys
    const canselCheckedkeys = hasCheckedkeys.filter((key) => !filterCheckedKeys.includes(key));
    // 增加的keys
    const addCheckedkeys = filterCheckedKeys.filter((key) => !hasCheckedkeys.includes(key));

    // 增加选中项
    if (addCheckedkeys.length) {
      const addCheckedValues = deepestData.filter((item) =>
        addCheckedkeys.includes(item.key) && !this.state.checkedKeys.includes(item.key));
      checkedValues = [...checkedValues, ...addCheckedValues];
    }
    // 去除取消选中项
    if (canselCheckedkeys.length) {
      checkedValues = checkedValues.filter((item: ITreeData) =>
        !canselCheckedkeys.includes(item.key));
    }

    this.props.onCheck(checkedKeys);
    this.setState({
      checkedValues,
      checkedKeys: filterCheckedKeys, // 值保存过滤后的key 要不删除会有问题
    });
  }

  public onSelect(selectedKeys: string[], info: any) {
    this.setState({ selectedKeys });
  }

  public onSave() {
    if (this.props.onSave) {
      this.props.onSave(this.state.checkedValues);
    }
  }

  public renderTreeNodes(data: any) {
    return data.map((item: any) => {
      if (item.children) {
        return (
          <TreeNode
            title={item.title}
            key={item.key}
          //   dataRef={item}
          // icon={({ selected }) => (
          //     <Icon type={selected ? 'check-circle' : 'warn-circle'} />
          //     <Icon type='check-circle'/>
          //   )}
          >
            {this.renderTreeNodes(item.children)}
          </TreeNode>
        );
      }
      return <TreeNode
        {...item}
      // icon={({ selected }) => (<Icon type='check-circle' />)}
      />;
    });
  }

  public emptySelect() {
    this.setState({ checkedKeys: [], checkedValues: [] });
  }

  public deleteSelect(key: string) {

    const { checkedKeys, checkedValues } = this.state;
    const newCheckedKeys = checkedKeys && checkedKeys.filter((checkedKey: string) => checkedKey !== key);
    const newCheckedValues = checkedValues && checkedValues.filter(
      (checkedValue: ITreeData) => checkedValue.key !== key,
    );
    this.setState({
      checkedKeys: [...newCheckedKeys],
      checkedValues: newCheckedValues,
    });
  }

  public getRightContentHeadRef(node: HTMLDivElement) {
    this.rightContentHead = node;
    this.setState({
      rightContentHeadHeight: (this.rightContentHead as any).offsetHeight,
    });
  }

  public getLeftContentHeadRef(node: HTMLDivElement) {
    this.leftContentHead = node;
    this.setState({
      leftContentHeadHeight: (this.leftContentHead as any).offsetHeight,
    });
  }

  public rendSearchInput() {
    const { searchPlaceholder, showSearch } = this.props;
    if (showSearch) {
      return (
        <div className="content-head" ref={this.getLeftContentHeadRef}>
          <Input
            type="text"
            placeholder={searchPlaceholder}
            className="input"
            afterIconType="info-circle"
            size="small"
            value={this.state.searchValue}
            onChange={this.inputTextChange}
          />
        </div>
      );
    }
    return null;
  }

  public inputTextChange(event: React.ChangeEvent<HTMLInputElement>) {
    const value = (event.target as any).value;
    if (this.props.onSearchInputChange) {
      this.props.onSearchInputChange(value)
        .then((treeData) => {
          this.setState({
            treeData,
          });
        }).catch((e) => {
          console.warn('调用onSearchInputChange失败', e);
        });
    } else {
      const treeData = this.props.treeData || [];
      const { values: newTreeData, expandedKeys } = this.getSearchDataAndExpandedKeys(treeData, value);
      if (newTreeData.length) {
        this.setState({
          treeData: newTreeData,
          expandedKeys,
        });
      } else {
        this.setState({
          treeData,
        });
      }
    }
    this.setState({
      searchValue: (event.target as any).value,
    });
  }

  public renderEmptySelect() {
    const props = this.props;
    if (props.showEmptySelect) {
      return (
        <div className="empty" onClick={this.emptySelect}>
          <Icon type="trash" color="#0a67b0" size={14}></Icon>
          <span className="empty-text">清空所有选择</span>
        </div>
      );
    }
    return null;
  }

  public renderDescriptionTitle() {
    const props = this.props;
    if (props.descriptionTitle) {
      return (
        <div className="description">
          <Icon type="info-circle" color="#ffa303" size={14}></Icon>
          <span className="description-title">{props.descriptionTitle}</span>
        </div>
      );
    }
  }

  public render() {
    const {
      showInnerSelectedTitle,
      showOuterSelectedTitle,
      onCancel,
    } = this.props;

    const { treeData } = this.state;

    const checkedValues = [...this.state.checkedValues];
    const checkedKeys = [...this.state.checkedKeys];
    return (
      <div className="bricks-transfer">
        {/* 头部内容 */}

        <div className="transfer-head clearfix">
          {this.renderDescriptionTitle()}
          < div className="head-right" >
            {showOuterSelectedTitle ? <span className="selected-text">已选择 ：</span > : null}
            {this.renderEmptySelect()}
          </div>
        </div>

        {/* 中间内容 */}
        <div className="transfer-content">
          {/* 左  框 */}
          <div className="transfer-content-left">
            {/* 搜索框 */}
            {this.rendSearchInput()}
            {/* 计算内容盒子的高度的等于父元素盒子的高度减去 头部的高度 */}
            <div className="content-box" style={{ height: `${330 - this.state.leftContentHeadHeight}px` }}>
              <Tree
                checkable
                showIcon
                onExpand={this.onExpand}
                expandedKeys={this.state.expandedKeys}
                autoExpandParent={this.state.autoExpandParent}
                onCheck={this.onCheck}
                checkedKeys={checkedKeys}
                onSelect={this.onSelect}
                selectedKeys={this.state.selectedKeys}
              >
                {this.renderTreeNodes(treeData)}
              </Tree>
            </div>
          </div>
          {/* 中间间隔 */}
          <div className="transfer-content-middle" >
            <Icon type="transfer" color="#a4a4a4" size={20}></Icon>
          </div>
          {/* 右 框 */}
          <div className="transfer-content-right" >
            {
              showInnerSelectedTitle ? (
                <div className="content-head" ref={this.getRightContentHeadRef}>
                  <div className="search">已选择结果</div>
                </div >
              ) : null
            }

            <div className="content-box" style={{ height: `${330 - this.state.rightContentHeadHeight}px` }}>
              {
                // props.selectedData.map((item: any) =>
                checkedValues.map((item: ITreeData) =>
                  (
                    <div className="clearfix" key={item.key}>
                      <span className="selected-result">{item.label || item.title}</span>
                      <span
                        className="selected-icon"
                        onClick={() => this.deleteSelect(item.key)}
                      >
                        <Icon type="close-solid" color="#e72d3a" size={14}></Icon>
                      </span>
                    </div>
                  ),
                )
              }
            </div>
          </div>
        </div>

        {/* 底部按钮 */}
        <div className="transfer-foot">
          <div className="btn-box">
            <button
              className="button button-primary button-sm"
              onClick={this.onSave}>
              保存
          </button>
            <button
              className="button button-outline button-sm"
              onClick={onCancel}>
              取消
          </button>
          </div>
        </div>
      </div>
    );

  }

}
